package Factory.Entities;

import Model.Core.IState;
import Model.Core.Impl.FinishState;
import Model.Core.Impl.StartState;
import Model.Core.Impl.State;
import Model.Diagrams.StateMachine;
import Model.Draw.Coordinate;
import Model.Draw.Entities.Impl.StateLine;
import Model.Draw.Entities.StateDraw;
import Model.Draw.Events.ManifestElementEvent;
import Model.Draw.Events.ManifestStateDoneListener;
import Model.Draw.Point;
import java.util.ArrayList;
import java.util.List;

/**
 * Projeto de TCC: Editor de Diagramas de comunicação BlueJ
 * @author Jose
 */
public class StateFactory {

    private List<ManifestStateDoneListener> listeners;

    public StateFactory() {
        listeners = new ArrayList<ManifestStateDoneListener>();
    }

    public void addListener(ManifestStateDoneListener listener) {
        if (!listeners.contains(listener)) {
            this.listeners.add(listener);
        }
    }

    public void removeListener(ManifestStateDoneListener listener) {
        this.listeners.remove(listener);
    }

    public void createStateGraphicalManifest(State state, Object sourceElement, Object targetElement) {
        Point source = (Point)sourceElement;
        Point target = (Point)targetElement;
        Point aux;
        if (source.getX().getCoordinate() > target.getX().getCoordinate()) {
            if (source.getY().getCoordinate() > target.getY().getCoordinate()) {
                aux = new Point(new Coordinate(source.getX().getCoordinate()), new Coordinate(source.getY().getCoordinate()));
                source = target;
                target = aux;
            } else {
                aux = new Point(new Coordinate(source.getX().getCoordinate()), new Coordinate(source.getY().getCoordinate()));
                source.setX(target.getX());
                target.setX(aux.getX());
            }
        } else {
            if (source.getY().getCoordinate() > target.getY().getCoordinate()) {
                aux = new Point(new Coordinate(source.getX().getCoordinate()), new Coordinate(source.getY().getCoordinate()));
                source.setY(target.getY());
                target.setY(aux.getY());
            }
        }
        StateDraw graphicalManifest = new StateDraw();
        Point supportPointY = new Point(target.getX(), source.getY());
        Point supportPointX = new Point(source.getX(), target.getY());
        graphicalManifest.setTop(new StateLine(source, supportPointY, state));
        graphicalManifest.setRight(new StateLine(supportPointY, target, state));
        graphicalManifest.setLeft(new StateLine(source, supportPointX, state));
        graphicalManifest.setBottom(new StateLine(supportPointX, target, state));
        state.setDraw(graphicalManifest);
        notifyListeners(state);
    }

    private void notifyListeners(IState state) {
        for (ManifestStateDoneListener listener : listeners) {
            listener.manifestStateDoneHandler(new ManifestElementEvent(state));
        }
    }

    public static StateMachine createStateMachine(String objectName) {
        StartState startEntity = new StartState();
        FinishState finishEntity = new FinishState();

        StateMachine stateMachine = new StateMachine(objectName, startEntity, finishEntity);
        return stateMachine;
    }

    public void createStartStateGraphicalManifest(StartState startState, Object sourceElement, Object targetElement) {
        
    }

    public void createFinishStateGraphicalManifest(FinishState finishState, Object sourceElement, Object targetElement) {
        
    }
}
